package com.cet.test.ybb;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: cet-practice
 * @description:
 * @author: 陈恩涛
 * @create: 2023-05-09 16:13
 **/
public class Client {

    public static void main(String[] args) {

        List<List<String>> strListList = Arrays.asList(
            Arrays.asList("A1", "A2", "A3", "A4"),
            Arrays.asList("B1", "B2", "B3", "B4", "B5", "B6"),
            Arrays.asList("C1", "C2", "C3", "C4", "C5"),
            Arrays.asList("D1", "D2")
        );

        System.out.println(Arrays.toString(getPossibleList(strListList).toArray(new List[0])));

    }

    public static<T>  List<List<Integer>> getPossibleList(List<List<T>> data) {

        // 结果集合
        List<List<Integer>> result = null;

        for (List<T> list : data) {

            //存放本次遍历后的临时结果
            List<List<Integer>> temp = new ArrayList<>();

            // 第一次循环
            if (result == null) {
                for (int i = 0; i < list.size(); i++) {
                    temp.add(Stream.of(i).collect(Collectors.toList()));
                }
                result = temp;
                continue;
            }
            // 不是第一次遍历
            // 用n-1次的笛卡尔积与当前list做笛卡尔积
            for (int i = 0; i < list.size(); i++) {
                for (List<Integer> lt : result) {
                    temp.add(Stream.concat(lt.stream(), Stream.of(i)).collect(Collectors.toList()));
                }
            }
            result = temp;

        }
        return result;
    }

    public static<T>  List<List<T>> cartesianProduct(List<List<T>> data) {

        // 结果集合
        List<List<T>> result = null;

        for (List<T> list : data) {

            //存放本次遍历后的临时结果
            List<List<T>> temp = new ArrayList<>();

            // 第一次循环
            if (result == null) {
                for (T t : list) {
                    temp.add(Stream.of(t).collect(Collectors.toList()));
                }
                result = temp;
                continue;
            }
            // 不是第一次遍历
            // 用n-1次的笛卡尔积与当前list做笛卡尔积
            for (T t : list) {
                for (List<T> lt : result) {
                    temp.add(Stream.concat(lt.stream(), Stream.of(t)).collect(Collectors.toList()));
                }
            }
            result = temp;

        }
        return result;
    }

}
